home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Matrix / VarMatrix.m < prev   
Text File  |  1995-06-12  |  9KB  |  368 lines

  1.  
  2.  
  3. /* A subclass of Matrix that allows variable size columns and rows */
  4. /* Creator : Imran Qureshi */
  5. /* August 3, 1992 */
  6. /* e-mail : cooldude@leland.stanford.edu */
  7. /*  Provided as FREEWARE  */
  8.  
  9. #import "VarMatrix.h"
  10. #import <appkit/TextFieldCell.h>
  11. #import <objc/List.h>
  12. #import <stdlib.h>
  13.  
  14. @implementation VarMatrix
  15.  
  16. -initFrame:(NXRect *)frameRect mode:(int)aMode prototype:aCell numRows:(int)rowsHigh numCols:(int)colsWide;
  17. {
  18.     int i;
  19.     column    *thisColPtr;
  20.     row        *thisRowPtr;
  21.     
  22.     [super initFrame:frameRect mode:aMode prototype:aCell 
  23.                             numRows:rowsHigh numCols:colsWide];
  24.     
  25.     columnList = [[List alloc] init];
  26.     rowList = [[List alloc] init];
  27.     
  28.     for (i=0; i < colsWide; i++) {
  29.         thisColPtr = (column*)calloc(1,sizeof(column));
  30.         [columnList addObject:(id)thisColPtr];
  31.         thisColPtr->x = i * cellSize.width;
  32.         thisColPtr->width = cellSize.width;
  33.     }
  34.     
  35.     for (i=0; i < rowsHigh; i++) {
  36.         thisRowPtr = (row*)calloc(1,sizeof(row));
  37.         [rowList addObject:(id)thisRowPtr];
  38.         thisRowPtr->y = i * cellSize.height;
  39.         thisRowPtr->height = cellSize.height;
  40.     }
  41.     {
  42.         NXRect    rect;
  43.                                      
  44.         [self getFrame:&rect];
  45.         rect.size.width =130.;
  46.         NXSetRect(&oldRect,rect.origin.x,rect.origin.y,
  47.                                      rect.size.width, rect.size.height);
  48.  
  49.         [self setFrame:&rect];
  50.     }
  51.     return self;
  52. }
  53. -erase
  54. {
  55.     NXRect    rect;
  56.     
  57.     [self lockFocus];
  58.     [self getFrame:&rect];
  59.     NXEraseRect(&rect);
  60.     [self unlockFocus];
  61.     return self;
  62. }
  63. -setWidth:(float)width forCol:(int)col
  64. {
  65.     float    diff;
  66.     
  67.     
  68.     diff = width - ((column*)[columnList objectAt:col])->width;
  69.     ((column*)[columnList objectAt:col])->width = width;
  70.     
  71.     [self updateColsFrom:col+1 with:diff];
  72.     
  73.     
  74.     return self;
  75. }
  76. -setHeight:(float)height forRow:(int)theRow
  77. {
  78.     float    diff;
  79.     
  80.     
  81.     diff = height - ((row*)[rowList objectAt:theRow])->height;
  82.     ((row*)[rowList objectAt:theRow])->height = height;
  83.     
  84.     [self updateRowsFrom:theRow+1 with:diff];
  85.     
  86.     return self;
  87. }
  88. -sizeToCells
  89. {
  90.     NXRect    rect;
  91.                                      
  92.     [self getFrame:&rect];
  93.     NXSetRect(&oldRect,rect.origin.x,rect.origin.y,
  94.                                      rect.size.width, rect.size.height);
  95.     rect.size.width = ((column*)[columnList lastObject])->x +
  96.                                      ((column*)[columnList lastObject])->width;
  97.     rect.size.height = ((row*)[rowList lastObject])->y +
  98.                                      ((row*)[rowList lastObject])->height;
  99.     [self setFrame:&rect];
  100.     
  101.     return self;
  102.  
  103. }
  104. -renewRows:(int)newRows cols:(int)newCols
  105. {
  106.     column    *rectPtr;
  107.     row        *rowPtr;
  108.     int        i;
  109.     
  110.     for (i=numCols; i < newCols; i++) {
  111.         rectPtr = (column*)calloc(1,sizeof(column));
  112.         [columnList addObject:(id)rectPtr];
  113.         rectPtr->x = i * cellSize.width;
  114.         rectPtr->width = cellSize.width;
  115.     
  116.     }
  117.     for (i=numRows; i < newRows; i++) {
  118.         rowPtr = (row*)calloc(1,sizeof(row));
  119.         [rowList addObject:(id)rowPtr];
  120.         rowPtr->y = i * cellSize.height;
  121.         rowPtr->height = cellSize.height;
  122.     
  123.     }
  124.  
  125.     [super renewRows:newRows cols:newCols];
  126.     return self;
  127. }
  128. -addCol
  129. {
  130.     column    *rectPtr;
  131.     float    place;
  132.     
  133.     rectPtr = (column*)calloc(1,sizeof(column));
  134.     place = ((column*)[columnList lastObject])->x +
  135.                                      ((column*)[columnList lastObject])->width;
  136.         
  137.     [columnList addObject:(id)rectPtr];
  138.     rectPtr->x = place;
  139.     rectPtr->width = cellSize.width;
  140.     
  141.     [super addCol];
  142.     return self;
  143. }
  144. - insertColAt:(int)col
  145. {
  146.     column        *rectPtr;
  147.     float    place,diff;
  148.     
  149.     rectPtr = (column*)calloc(1,sizeof(column));
  150.     place = ((column*)[columnList objectAt:col-1])->x +
  151.                             ((column*)[columnList objectAt:col-1])->width;
  152.         
  153.     [columnList insertObject:(id)rectPtr at:col];
  154.     rectPtr->x = place;
  155.     rectPtr->width = cellSize.width;
  156.  
  157.     diff = cellSize.width;
  158.     
  159.     [self updateColsFrom:col+1 with:diff];
  160.     
  161.     return [super insertColAt:col];
  162.     
  163. }
  164. - removeColAt:(int)col andFree:(BOOL)flag
  165. {
  166.     float    diff;
  167.     
  168.     /*  is negative 'cause we want to subtract this height from the rest */
  169.     diff = -((column*)[columnList objectAt:col])->width;
  170.     [columnList removeObjectAt:col];
  171.     
  172.     [self updateColsFrom:col with: diff];
  173.     
  174.     return [super removeColAt:col andFree:flag];
  175. }
  176. -addRow
  177. {
  178.     row        *rectPtr;
  179.     float    place;
  180.     
  181.     rectPtr = (row*)calloc(1,sizeof(row));
  182.     place = ((row*)[rowList lastObject])->y +
  183.                                      ((row*)[rowList lastObject])->height;
  184.         
  185.     [rowList addObject:(id)rectPtr];
  186.     rectPtr->y = place;
  187.     rectPtr->height = cellSize.height;
  188.     
  189.     return [super addRow];
  190. }
  191. - insertRowAt:(int)theRow
  192. {
  193.     row        *rectPtr;
  194.     float    place,diff;
  195.     
  196.     rectPtr = (row*)calloc(1,sizeof(row));
  197.     place = ((row*)[rowList objectAt:theRow-1])->y +
  198.                             ((row*)[rowList objectAt:theRow-1])->height;
  199.         
  200.     [rowList insertObject:(id)rectPtr at:theRow];
  201.     rectPtr->y = place;
  202.     rectPtr->height = cellSize.height;
  203.  
  204.     diff = cellSize.width;
  205.     
  206.     [self updateRowsFrom:theRow+1 with:diff];
  207.     
  208.     return [super insertRowAt:theRow];
  209.     
  210. }
  211. - removeRowAt:(int)theRow andFree:(BOOL)flag
  212. {
  213.     float    diff;
  214.     
  215.     /*  is negative 'cause we want to subtract this height from the rest */
  216.     diff = -((row*)[rowList objectAt:theRow])->height;
  217.     [rowList removeObjectAt:theRow];
  218.     
  219.     [self updateRowsFrom:theRow with: diff];
  220.     
  221.     return [super removeRowAt:theRow andFree:flag];
  222. }
  223.  
  224. -updateRowsFrom:(int)rowNum with:(float)diff
  225. {
  226.     int        i;
  227.     for (i=rowNum; i < [rowList count] ; i++) {
  228.         ((row*)[rowList objectAt:i])->y += diff;
  229.     }
  230.     return self;
  231. }
  232. -updateColsFrom:(int)colNum with:(float)diff
  233. {
  234.     int        i;
  235.     for (i=colNum; i < [columnList count] ; i++) {
  236.         ((column*)[columnList objectAt:i])->x += diff;
  237.     }
  238.     return self;
  239. }
  240.  
  241. -update
  242. {
  243.     int    col,row;
  244.     NXRect    rect;
  245.     
  246.     //printf("update\n");
  247.     if ([self superview] == NULL) return [super update];
  248.     [self erase];
  249.     for (col = 0; col < [columnList count]; col++) {
  250.         for (row = 0; row < [rowList count]; row++) {
  251.             [self drawCellAt:row :col];
  252.         }
  253.     }
  254.     
  255.     [self getFrame:&rect];
  256.     NXSetRect(&oldRect,rect.origin.x,rect.origin.y,
  257.                                      rect.size.width, rect.size.height);
  258.     return self;
  259. }
  260. -drawCellAt:(int)theRow :(int)col
  261. {
  262.     NXRect    cellFrame = {0.0,0.0,20.0,20.0};
  263.     //printf("drawCellAt: %d :%d\n",theRow,col);
  264.     //[super drawCellAt:row :col];
  265.     cellFrame.origin.x = ((column*)[columnList objectAt:col])->x;
  266.     cellFrame.origin.y = ((row *)[rowList objectAt:theRow])->y;
  267.     cellFrame.size.width =((column*)[columnList objectAt:col])->width;
  268.     cellFrame.size.height =((row*)[rowList objectAt:theRow])->height;
  269.     [self lockFocus];
  270.     
  271.     [[self cellAt:theRow :col] drawSelf:&cellFrame inView:self];
  272.     [self unlockFocus];
  273.     return self;
  274. }
  275. -drawSelf:(const NXRect *)rects :(int)rectCount
  276. {
  277.     NXRect    rect;
  278.     
  279.     //printf("drawSelf: %d\n",rectCount);
  280.     [self getFrame:&rect];
  281.     NXEraseRect(&rect);
  282.     
  283.     [super drawSelf:rects :rectCount];
  284.     return self;
  285. }
  286. -getCellFrame:(NXRect *)theRect at:(int)theRow :(int)col
  287. {
  288.     //printf("getCellFrame at:%d :%d\n",theRow,col);
  289.     //[super getCellFrame:theRect at:row :col];
  290.     
  291.     NXSetRect(theRect,((column*)[columnList objectAt:col])->x,
  292.             ((row *)[rowList objectAt:theRow])->y,
  293.             ((column*)[columnList objectAt:col])->width,
  294.             ((row*)[rowList objectAt:theRow])->height);
  295.     return self;
  296. }
  297. -getRow:(int *)theRow andCol:(int*)col forPoint:(const NXPoint *)point
  298. {
  299.     int     i;
  300.     //printf("getRow\n");
  301.     
  302.     *theRow = -1;
  303.     *col = -1;
  304.     
  305.     for (i = 0; i < [columnList count]; i++) {
  306.         if ((point->x >= (((column*)[columnList objectAt:i])->x)) &&
  307.             (point->x <= ((((column*)[columnList objectAt:i])->x) +
  308.                  ((column*)[columnList objectAt:i])->width))) {
  309.             *col =i;
  310.         }
  311.     }
  312.     for (i = 0; i < [rowList count]; i++) {
  313.         if ((point->y >= (((row*)[rowList objectAt:i])->y)) &&
  314.             (point->y <= ((((row*)[rowList objectAt:i])->y) +
  315.                  ((row*)[rowList objectAt:i])->height))) {
  316.             *theRow =i;
  317.         }
  318.     }
  319.     return self;
  320. }
  321. -getRow:(int *)row andCol:(int *)col ofCell:aCell
  322. {
  323.     //printf("getRow for cell\n");
  324.     //[aCell getDrawRect:&rect];
  325.     //*row = abs(rect.origin.y/20.0);
  326.     //*col = abs(rect.origin.x/20.0);
  327.     [super getRow:row andCol:col ofCell:aCell];
  328.     return self;
  329. }
  330. - mouseDown:(NXEvent *)theEvent
  331. {
  332.     NXPoint        mouseDownLocation;
  333.     int            row, column;
  334.     id            activeCell;
  335.       
  336.     //printf("mouseDown:\n");
  337.   /* find the cell that got clicked on and select it */
  338.     mouseDownLocation = theEvent->location;
  339.     [self convertPoint:&mouseDownLocation fromView:nil];
  340.     [self getRow:&row andCol:&column forPoint:&mouseDownLocation];
  341.     activeCell = [self cellAt:row :column];
  342.     [self selectCell:activeCell];
  343.     //[self getCellFrame:&cellFrame at:row :column];
  344.     
  345.   /* do whatever's required for a single-click */
  346.     [self sendAction];
  347.     
  348.       return self;
  349. }
  350.  
  351. -write:(NXTypedStream*)typedStream
  352. {
  353.     [super write:typedStream];
  354.     NXWriteObject(typedStream,rowList);
  355.     NXWriteObject(typedStream,columnList);
  356.     return self;
  357. }
  358. -read:(NXTypedStream*)typedStream
  359. {
  360.     [super read:typedStream];
  361.     
  362.     rowList = NXReadObject(typedStream);
  363.     columnList = NXReadObject(typedStream);
  364.     return self;
  365. }
  366.  
  367. @end
  368.